/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package phoneThreads;

import domen.Application;
import communication.*;
import domen.Downloadinfo;
import ejb.ApplicationFacade;
import ejb.DownloadinfoFacade;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 *
 * @author Danilo
 */
public class ClientThread extends Thread {

    private Socket socket;
    private ApplicationFacade appFacade;
    private DownloadinfoFacade dowFacade;
    private PhoneThread pt;

    public ClientThread(Socket socket, PhoneThread pt) {
        this.socket = socket;
        this.pt = pt;
        try {
            appFacade = (ApplicationFacade) new InitialContext().lookup("java:global/SrbDroid/ApplicationFacade");
            dowFacade = (DownloadinfoFacade) new InitialContext().lookup("java:global/SrbDroid/DownloadinfoFacade");
        } catch (NamingException ex) {
            Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        }
        start();
    }

    @Override
    public void run() {
        while (!this.isInterrupted()) {
            try {
                this.sleep(200);
                if (getSocket().getInputStream().available() == 0) {
                    continue;
                }
                ObjectInputStream ois = new ObjectInputStream(getSocket().getInputStream());
                TransferObject to = (TransferObject) ois.readObject();
                switch (Messages.type(to.getMessage())) {
                    case CONNECT:
                        pt.getClients().put(to.getObject().toString(), socket);
                    case DISCONNECT:
                        this.interrupt();
                        break;
                    case APPLIST:
                        sendApplications(to.getObject());
                        break;
                    case APP_INFO:
                        sendAppInfo(to.getObject());
                        break;
                    case DOWNLOAD:
                        downloadAPK(to.getObject());
                        break;
                    case VOTE:
                        voteApplication(to);
                        this.interrupt();
                        break;
                    case SEARCH:
                        searchForApplication(to.getObject());
                        break;
                    case DOWNLOAD_FINISHED:
                        downloadFinished(to);
                        break;
                }
            } catch (Exception ex) {
                System.out.println(ex);
            }

        }
    }

    private void sendApplications(Object object) {
        if (object == null) {
            sendTopListApplication();
        }
    }

    private void downloadAPK(Object object) {
        try {
            int appId = (Integer) object;
            prepareForDownload(appId);
        } catch (IOException ex) {
            Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void voteApplication(TransferObject object) {
    }

    private void sendTopListApplication() {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(getSocket().getOutputStream());
            oos.writeObject(new TransferObject(Messages.token(Messages.APPLIST), appFacade.getTopListApplication().toArray()));
        } catch (IOException ex) {
            Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void searchForApplication(Object object) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(getSocket().getOutputStream());
            oos.writeObject(new TransferObject(Messages.token(Messages.APPLIST), appFacade.searchForApplication(object.toString()).toArray()));
        } catch (IOException ex) {
            Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void prepareForDownload(int appId) throws IOException {
        Application app = appFacade.find(appId);
        app.setDownloads(app.getDownloads() + 1);
        appFacade.edit(app);
        String url = "http://srbdroid.no-ip.info/downloadAPK?appId=" + app.getApplicationId();
        downloadReady(url);
    }

    private void downloadReady(String url) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(getSocket().getOutputStream());
        oos.writeObject(new TransferObject(Messages.token(Messages.DOWNLOAD), url));
    }

    private void downloadFinished(TransferObject object) {
        Downloadinfo di = new Downloadinfo(object.getIMEI(), new Date());
        di.setApplications(appFacade.find(object.getObject()));
        dowFacade.create(di);
    }

    /**
     * @return the socket
     */
    public Socket getSocket() {
        return socket;
    }

    private void sendAppInfo(Object object) throws IOException {
        int id = (Integer) object;
        ObjectOutputStream oos = new ObjectOutputStream(getSocket().getOutputStream());
        oos.writeObject(new TransferObject(Messages.token(Messages.APP_INFO), appFacade.getApplicationInfo(id)));
    }
}
